#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>

sem_t sem_empty;
sem_t sem_full;

// 设置仓库的大小为10
// 值为0 表示该位置为空
// 值为1 表示该位置存储了商品
int Warehouse[10] = {10};

// 定义两个指针
int in = 0;
int out = 0;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// 打印所有商品
void printWarehouse() {
	printf("Warehouse:");
	for (int i = 0; i < 10; i++) {
		printf("[%d] ", Warehouse[i]);
	}
	printf("\n");
}


void* producterThd(void* arg) {

	for (int i = 0; i < 20; i++) {
		// printf("Producter producing one item.\n");
		
		sem_wait(&sem_empty);
		
		// 临界区开始
		// 由于多个线程同时操作 Warehouse 数组，这里需要上锁
		pthread_mutex_lock(&lock);
		
		Warehouse[in] = 1;
		// 防止数组越界
		in = (in + 1) % 10;
		printWarehouse();
		// 设置生产比消费快
		sleep(0.1);
		
		// 临界区结束
		pthread_mutex_unlock(&lock);
		
		sem_post(&sem_full);
		
		// printf("Producter putting item to warehouse.\n");
	}

	pthread_exit(0);
}

void* consumerThd(void* arg) {

	for (int i = 0; i < 20; i++) {
		// printf("Consumer getting item from warehouse.\n");
		
		// printf("Consumer consuming the item\n");
		
		sem_wait(&sem_full);
		
		pthread_mutex_lock(&lock);
		
		Warehouse[out] = 0;
		out = (out + 1) % 10;
		printWarehouse();
		
		sleep(1);
		
		pthread_mutex_unlock(&lock);
		
		sem_post(&sem_empty);
		
	}

	pthread_exit(0);
}

int main() {

	// 默认所有仓库都是空的，即 sem_empty 信号量为10，sem_full 信号量为0
	sem_init(&sem_empty, 0, 10);
	sem_init(&sem_full, 0, 0);

	pthread_t producter_tid;
	pthread_t consumer_tid;
	
	pthread_create(&producter_tid, NULL, producterThd, NULL);
	pthread_create(&consumer_tid, NULL, consumerThd, NULL);
	
	pthread_join(producter_tid, NULL);
	pthread_join(consumer_tid, NULL);
	
	sem_destroy(&sem_empty);
	sem_destroy(&sem_full);

	return 0;
}
